外观
2025年03月 GESP C++ 四级真题解析
一、单选题(每题2分,共30分)
选择题答案
| 题号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 答案 | A | B | B | D | D | C | D | D | B | B | B | B | A | A | C |
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限1. 关于下述代码,说法错误的是()。
cpp
int multiply(int x, int y);
int main() {
int a = 4;
int b = 5;
int result = multiply(a, b);
std::cout << "The result is: " << result << std::endl;
return 0;
}
int multiply(int x, int y) {
return x * y;
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
A. 函数 multiply 的定义应该放到函数 main 之前。
B. 函数声明 int multiply(int x, int y); 中明确指定了函数 multiply() 的返回值为整数类型。
C. 在 main 函数中,函数 multiply 通过 multiply(a, b) 被调用,其中 a 和 b 是定义在 main 函数中的变量,它们作为实参传递给了 multiply 函数的形参 x 和 y。
D. 运行上述代码,将输出 The result is: 20。
查看解析
答案:A
考纲知识点: 函数声明与定义顺序
解析: 当函数在调用前已有声明(第1行),定义可放在调用之后;因此“必须放前面”是错误的。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限2. 执行下述代码将输出()。
cpp
int x = 10;
void func() {
int x = 20;
std::cout << x;
}
int main() {
func();
std::cout << x;
return 0;
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
A. 2020
B. 2010
C. 1010
D. 编译错误
查看解析
答案:B
考纲知识点: 作用域遮蔽
解析: func 内局部变量 x=20 遮蔽全局变量,先输出 20,再输出全局 10,结果是 2010。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限3. 执行下述代码后,变量 a 的值为()。
cpp
int a = 10;
int* p = &a;
*p = 20;1
2
3
2
3
A. 10
B. 20
C. 随机值
D. 编译错误
查看解析
答案:B
考纲知识点: 指针与变量
解析: p 指向 a,*p = 20 直接修改 a 的值。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限4. 以下哪种参数传递方式可以避免拷贝大型对象?
A. 只能用值传递
B. 只能用引用传递
C. 只能用指针传递
D. 引用传递和指针传递均可
查看解析
答案:D
考纲知识点: 参数传递与性能
解析: 引用和指针均传递地址,避免整对象复制。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限5. 执行下述代码,将输出()。
cpp
void swap(int a, int &b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 1, y = 2;
swap(x, y);
std::cout << x << y;
return 0;
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
A. 12
B. 21
C. 22
D. 11
查看解析
答案:D
考纲知识点: 引用参数
解析: a 是值传递(不变),b 是引用传递(变为 1),因此 x 仍为 1,y 为 1,输出 11。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限6. 下面的描述中,()正确定义一个名为 Person 的结构体并正确初始化了一个 Person 结构体的变量 p。
A.
cpp
struct Person
string name;
int age;
};
Person p("Yang", 10);1
2
3
4
5
2
3
4
5
B.
cpp
struct Person {
string name, int age;
};
Person p;
p.name = "Yang";
p.age = 10;1
2
3
4
5
6
2
3
4
5
6
C.
cpp
struct Person {
string name;
int age;
};
Person p = { "Yang", 10 };1
2
3
4
5
2
3
4
5
D.
cpp
struct Person
string name;
int age;
};
Person p = new Person("Yang", 10);1
2
3
4
5
2
3
4
5
查看解析
答案:C
考纲知识点: 结构体定义与列表初始化
解析: C 语法正确;A/B 定义语法错误;D 把指针赋给对象,类型不匹配。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限7. 给定如下代码,下面描述错误的是()。
cpp
struct Person {
std::string name;
int age;
struct Address {
std::string street;
std::string city;
};
Address address;
};1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
A. 结构 Person 内嵌套结构 Address
B. Person 有一个 Address 类型的 address 成员
C. 一个 Person 类型的变量 p 的 address 的初始化可以写成:p.address.street = "123 Main St"; p.address.city = "Anytown";
D. 结构的嵌套可以减少命名冲突,因此可以不必控制嵌套层次
查看解析
答案:D
考纲知识点: 嵌套结构体
解析: 嵌套虽可减少命名冲突,但过度嵌套会降低可读性维护性,因此仍需控制层次。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限8. 假设 int arr[2][3] = {{1,2,3},{4,5,6}};,则 arr[1][2] 的值是()。A. 2
B. 3
C. 5
D. 6
查看解析
答案:D
考纲知识点: 二维数组索引
解析: 下标从 0 开始,第二行第三列元素为 6。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限9. 下面()正确定义了二维数组。
A. int arr[3,4];
B. int arr[3][4];
C. int arr(3,4);
D. int a[3-4];
查看解析
答案:B
考纲知识点: 二维数组语法
解析: 只有 B 使用正确的中括号语法。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限10. 小杨正在爬楼梯,每次可爬 1 或 2 阶,下面递推代码横线应填()。
cpp
int f(int n){
if (n == 1 || n == 2) return n;
int f1 = 1, f2 = 2, res = 0;
for (int i = 3; i <= n; ++i){
// 在此处填入代码
}
return res;
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
A. res += f1 + f2; f1 = f2; f2 = res;
B. res = f1 + f2; f1 = f2; f2 = res;
C. res += f1 + f2; f2 = res; f1 = f2;
D. res = f1 + f2; f2 = res; f1 = f2;
查看解析
答案:B
考纲知识点: 递推关系
解析: 需先计算新值 res = f1 + f2,再滑动窗口:f1 = f2; f2 = res;。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限11. 给定算法的时间复杂度为()。
cpp
bool f(int arr[], int n, int target){
for (int i = 0; i < (1 << n); ++i){
int sum = 0;
for (int j = 0; j < n; ++j)
if (i & (1 << j)) sum += arr[j];
if (sum == target) return true;
}
return false;
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
A. O(n²)
B. O(n × 2ⁿ)
C. O(1)
D. O(n³)
查看解析
答案:B
考纲知识点: 复杂度分析
解析: 外层 2ⁿ 种状态,内层 n 次求和,总复杂度 O(n·2ⁿ)。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限12. 下面关于排序稳定性的描述,正确的是()。
A. 稳定性指算法的时间复杂度恒定
B. 稳定排序保证相同元素的相对顺序不变
C. 选择排序是稳定排序
D. 插入排序不是稳定排序
查看解析
答案:B
考纲知识点: 排序稳定性
解析: B 定义准确;选择排序不稳定;插入排序稳定。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限13. 对数组 arr[] = {5,3,8,1} 执行第一轮冒泡排序后数组内容为()。
A. 3,5,1,8
B. 3,1,5,8
C. 3,5,8,1
D. 5,3,8,1
查看解析
答案:A
考纲知识点: 冒泡排序过程
解析: 第一轮将最大值 8 冒到末尾,中间交换顺序得 3,5,1,8。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限14. 运行下面代码,将出现()。
cpp
double hmean(double a, double b){
if (a == -b)
throw runtime_error("Runtime error occurred.");
return 2.0 * a * b / (a + b);
}
int main(){
double x = 10, y = -10;
try {
int result = hmean(x, y);
cout << "hmean: " << result << endl;
} catch (const runtime_error& e){
cout << "Caught:" << e.what() << endl;
} catch (...){
cout << "Caught an unknown exception." << endl;
}
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
A. 屏幕上输出 Caught:Runtime error occurred.
B. 屏幕上输出 Caught an unknown exception.
C. 程序调用 std::terminate()
D. 编译错误
查看解析
答案:A
考纲知识点: 异常处理
解析: a == -b 成立,抛出 runtime_error,被最匹配的 catch 捕获。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限15. 下面哪种方式不能实现将字符串 "Happy Spring!" 输出重定向到文件 log.txt( )。
A.
cpp
freopen("log.txt", "w", stdout);
cout << "Happy Spring!" << endl;
fclose(stdout);1
2
3
2
3
B.
cpp
std::ofstream outFile("log.txt");
outFile << "Happy Spring!" << endl;
outFile.close();1
2
3
2
3
C.
cpp
std::ofstream outFile("log.txt");
cout << "Happy Spring!" << endl;
outFile.close();1
2
3
2
3
D.
cpp
ofstream log_file("log.txt");
streambuf* org_cout = cout.rdbuf();
cout.rdbuf(log_file.rdbuf());
cout << "Happy Spring!" << endl;
cout.rdbuf(org_cout);1
2
3
4
5
2
3
4
5
查看解析
答案:C
考纲知识点: C++ 文件重定向
解析:
- A 利用
freopen把标准输出重定向到文件; - B 直接通过
ofstream写入文件; - D 通过替换
cout的缓冲区实现重定向; - C 虽然创建了
ofstream,但cout并未与其关联,输出仍到屏幕,无法写入文件,因此 C 不能实现重定向。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限二、判断题(每题2分,共20分)
判断题答案
| 题号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| 答案 | √ | × | √ | × | × | √ | √ | × | × | √ |
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限1. 函数是 C++ 中的核心概念,用于封装可重用的代码块。
查看解析
答案:√
解析: 定义准确。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限2. 在 C++ 中,函数的返回类型可以省略,默认为 int。
查看解析
答案:×
解析: C++ 必须显式指定返回类型;C 语言可默认 int。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限3. 结构体的成员默认是 public 访问权限。
查看解析
答案:√
解析: struct 成员默认 public;class 默认 private。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限4. 假设整数数组 arr[4] = {0,1,2,3} 的首地址为 0x7ffee4065820,经 int* p = arr; p += 1; 后,指针 p 的值是 1。
查看解析
答案:×
解析: p 指向第二个元素,地址为 0x...824,而非数值 1。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限5. 二维数组作为函数参数时,必须显式指定所有维度的大小。
查看解析
答案:×
解析: 只需第二维及以后维度大小,第一维可省略。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限6. 递推是一种通过已知的初始值和递推公式,逐步求解目标值的算法。
查看解析
答案:√
解析: 定义正确。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限7. 最坏情况下冒泡排序的递推关系式为 T(n) = T(n-1) + n, T(0) = 1。
查看解析
答案:√
解析: 每轮比较次数递减,累加得 O(n²)。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限8. 插入排序在最好情况(已有序)下的时间复杂度是 O(n²)。
查看解析
答案:×
解析: 最好情况只需线性扫描,为 O(n)。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限9. 对数组 {4,3,1,5,2} 执行第一轮选择排序后数组为 {1,4,3,5,2}。
查看解析
答案:×
解析: 选择最小值 1 与 4 交换,结果应该为 {1,3,4,5,2}。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限10. 未捕获异常会调用 std::terminate 终止程序。
查看解析
答案:√
解析: 符合 C++ 异常机制。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限三、编程题(每题 25 分,共 50 分)
1. 荒地开垦
题目描述
小杨有一块荒地,表示为一个 n 行 m 列的网格图。
- 每个格子要么是荒地
.,要么是杂物#。 - 一块荒地 可以开垦 当且仅当它的 上下左右四个邻格(若存在)都 没有杂物。
- 小杨可以 至多清除一个杂物格子 使其变为荒地。
求在 至多清除一个杂物 的前提下,最多能开垦多少块荒地。
输入格式
- 第 1 行:两个正整数 n, m。
- 接下来 n 行:每行一个长度为 m 的字符串,仅含
.与#。
输出格式
一行一个整数:最多可开垦的荒地块数。
样例输入 1
3 5
.....
.#..#
.....1
2
3
4
2
3
4
样例输出 1
111
数据范围
- 1 ≤ n, m ≤ 1000
解题思路
查看解题思路
考纲知识点
- 二维数组遍历
- 四连通邻域判断
- 贪心思想(枚举移除每个杂物后新增的开垦块)
解题思路
- 直接开垦:统计四周均无障碍的荒地数目。
- 移除杂物:枚举每一个杂物格子,计算若把它改成荒地后,四周新形成的可开垦荒地数目。
- 最大值:直接开垦数 + 通过移除一个杂物能带来的最大增量。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限参考程序
查看参考程序
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
char mat[N][N];
int add[N][N]; // add[i][j] 表示把(i,j)杂物改为荒地后新增的合法开垦数
const int dx[4] = {-1, 1, 0, 0};
const int dy[4] = {0, 0, -1, 1};
int main() {
int n, m, ans = 0;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
scanf("%s", mat[i] + 1);
/* 预处理:计算每个格子四周障碍数 */
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) {
int cnt = 0, dir = -1;
for (int k = 0; k < 4; ++k) {
int ni = i + dx[k], nj = j + dy[k];
if (ni < 1 || ni > n || nj < 1 || nj > m) continue;
if (mat[ni][nj] == '#') ++cnt;
}
/* 直接开垦 */
if (mat[i][j] == '.' && cnt == 0) ++ans;
/* 移除杂物带来的增量 */
else if (mat[i][j] == '.' && cnt == 1) {
for (int k = 0; k < 4; ++k) {
int ni = i + dx[k], nj = j + dy[k];
if (ni < 1 || ni > n || nj < 1 || nj > m) continue;
if (mat[ni][nj] == '#') ++add[ni][nj];
}
}
else if (mat[i][j] == '#' && cnt == 0) {
/* 该杂物四周无障碍,移除后自身成为可开垦荒地 */
++add[i][j];
}
}
int mx = 0;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
mx = max(mx, add[i][j]);
cout << ans + mx << endl;
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限2. 二阶矩阵
题目描述
给定一个 n 行 m 列的整数矩阵。
一个 2×2 的子矩阵被称为 “好的”,当且仅当a[i][j] * a[i+1][j+1] == a[i+1][j] * a[i][j+1]。
求矩阵中 好的 2×2 子矩阵 的数量。
输入格式
- 第 1 行:两个正整数 n, m。
- 接下来 n 行:每行 m 个整数。
输出格式
一行一个整数:好的 2×2 子矩阵数量。
样例输入 1
3 4
1 2 1 0
2 4 2 1
0 3 3 01
2
3
4
2
3
4
样例输出 1
21
数据范围
- 1 ≤ n, m ≤ 500
- −100 ≤ 元素值 ≤ 100
解题思路
查看解题思路
考纲知识点
- 二维数组遍历
- 子矩阵枚举
解题思路
遍历所有可能的左上角 (i, j),其中 1 ≤ i ≤ n-1,1 ≤ j ≤ m-1,检查 2×2 子矩阵是否满足给定等式。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限参考程序
查看参考程序
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
int a[N][N];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m, ans = 0;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
cin >> a[i][j];
for (int i = 1; i < n; ++i)
for (int j = 1; j < m; ++j)
if (a[i][j] * a[i + 1][j + 1] == a[i + 1][j] * a[i][j + 1])
++ans;
cout << ans << '\n';
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限